package visual;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.image.BufferStrategy;

import javax.swing.JFrame;

public class ValuePerTime extends JFrame {

        int[] _timetics;
        int _fieldBorderX = 30;
        int _fieldBorderY = 50;
        int _maximal;
        int _minimal;
        int _current;
        double _average;
        int _counts;
        private double _scale;
        private boolean _autoScale;
       
        public ValuePerTime(){
                init();
        }
       
        public ValuePerTime(String name) {
                super(name);
                init();
        }
       
        private void init()
        {
                this.createBufferStrategy(1);
               
                this.setBounds(10, 10, 270, 300);
                _timetics = new int[200];
                _maximal = 0;
                _minimal = 0;
                _current = 0;
                _average = 0;
                _counts = 0;
                _scale = 1;
                initTimetics();
        }

        private void initTimetics() {
                for (int i = 0; i < _timetics.length; i++) {
                        _timetics[i] = 0;
                }
        }

        public void addData(int value) {
                if (_counts == 0) {
                        _minimal = value;
                        _maximal = value;
                }
                _average = (_average * _counts + value) / (_counts + 1);
                _counts++;
                if (_counts > (100000)) {
                        _counts = 0;
                        _average = 0;
                }
                if (value > _maximal) {
                        _maximal = value;
                }
                if (value < _minimal) {
                        _minimal = value;
                }

                _current = (_current + 1) % _timetics.length;

                _timetics[_current] = value;
                this.repaint(0, 0, getWidth(), getHeight());
        }

        public void setAutoScale(boolean enable) {
                _autoScale = enable;
                _scale = 100;
        }

        public void paint(Graphics g) {
                BufferStrategy bf = this.getBufferStrategy();
                Graphics bufferGraphics = null;

                bufferGraphics = bf.getDrawGraphics();

                bufferGraphics.setColor(Color.white);
                bufferGraphics.fillRect(0, 0, getWidth(), getHeight());
                bufferGraphics.setColor(Color.black);
                bufferGraphics.drawString("Max: " + _maximal, _fieldBorderX + 60,
                                _fieldBorderY + 220);
                bufferGraphics.drawString("Min: " + _minimal, _fieldBorderX,
                                _fieldBorderY + 220);
                bufferGraphics.drawString("Now: " + _timetics[_current],
                                _fieldBorderX + 120, _fieldBorderY + 220);
                bufferGraphics.drawString("Avrg: " + _average, _fieldBorderX,
                                _fieldBorderY - 10);

                bufferGraphics.setColor(Color.white);
                bufferGraphics.fillRect(_fieldBorderX, _fieldBorderY, 201, 201);
                bufferGraphics.setColor(Color.black);
                bufferGraphics.drawRect(_fieldBorderX, _fieldBorderY, 201, 201);
                bufferGraphics.setColor(new Color(125, 0, 125));
                drawData(bufferGraphics);

                // It is best to dispose() a Graphics object when done with it.
                bufferGraphics.dispose();

                // Shows the contents of the backbuffer on the screen.
                bf.show();

                // Tell the System to do the Drawing now, otherwise it can take a few
                // extra ms until
                // Drawing is done which looks very jerky
                Toolkit.getDefaultToolkit().sync();

        }

        private void drawData(Graphics g) {
                if (((_maximal > (200 / 2) / _scale) || (Math.abs(_minimal) > (200 / 2)
                                / _scale))
                                && (_autoScale)) {

                        _scale = (200 / 2d) / Math.max(_maximal, Math.abs(_minimal));
                }

                for (int i = 0; i < _timetics.length; i++) {
                        g.drawLine(i + 1 + _fieldBorderX, _fieldBorderY + 100, i + 1
                                        + _fieldBorderX,
                                        (_fieldBorderY + 100)
                                                        - (int) (_timetics[(_current + 1 + i)
                                                                        % _timetics.length] * _scale));
                }
                g.setColor(Color.red);
                g.drawLine(_fieldBorderX, _fieldBorderY + 100
                                - (int) (_average * _scale), _fieldBorderX + 200,
                                +_fieldBorderY + 100 - (int) (_average * _scale));
        }
} 